
package com.auth.config.filter.provider;

import com.auth.config.exception.AuthException;
import com.auth.config.filter.client.ClientDetailsServiceAuth;
import com.auth.config.token.CustomAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Component;


/**
 *
 *  UsernameAuthenticationProvider 主要对登录的用户和密码进行筛选
 * @author: hw
 * @date: 2020/11/26 20:58
 */
@Slf4j
@Component
public class PhoneAuthenticationProvider extends ClientDetailsServiceAuth implements AuthenticationProvider{


    @Autowired private UserDetailsService userDetailsService;

    @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder;




    @Override
    public Authentication authenticate(Authentication authentication)  {
        log.info("JwtAuthenticationTokenFilter自定义过滤器");
        User userDetails = (User) userDetailsService.loadUserByUsername(authentication.getName());

        if (userDetails.getAuthorities().isEmpty()){
            throw new AuthException("无任何权限无法登录");
        }
        if (!userDetails.isEnabled()){
            throw new AuthException("用户已停用，无法登录");
        }
        if (!userDetails.isAccountNonExpired()){
            throw new AuthException("用户已注销，无法登录");
        }
        if (!bCryptPasswordEncoder.matches(authentication.getCredentials()+"",userDetails.getPassword())){
            throw new AuthException("用户密码错误，无法登录");
        }
        CustomAuthenticationToken customAuthenticationToken = (CustomAuthenticationToken) authentication;
        /**
         *  坑点-：
         *      构造必须是UsernamePasswordAuthenticationToken 等自带的token类否则会在解析时反序列化类时错误
         */
        return new OAuth2Authentication(super.createOAuth2Request(customAuthenticationToken.getAppId(), customAuthenticationToken.getRedirectUrl()),
                new UsernamePasswordAuthenticationToken( userDetails, userDetails.getPassword(), userDetails.getAuthorities()));

    }



    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(
                CustomAuthenticationToken.class);
    }

}
